home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / xcdplayer / cdrom_callb.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  17KB  |  751 lines

  1. /*
  2.  * Copyright (C) 1990 Regents of the University of California.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee,
  6.  * provided that the above copyright notice appear in all copies and that
  7.  * both that copyright notice and this permission notice appear in
  8.  * supporting documentation, and that the name of the University of
  9.  * California not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  the University of California makes no representations
  12.  * about the suitability of this software for any purpose.  It is provided
  13.  * "as is" without express or implied warranty.
  14.  */
  15.  
  16. # include <X11/Intrinsic.h>
  17. # include <X11/StringDefs.h>
  18. # include <X11/Xaw/Form.h>
  19. # include <X11/Xaw/Toggle.h>
  20.  
  21. # include <stdio.h>
  22.  
  23. # include "debug.h"
  24. # include "cdrom_globs.h"
  25. #ifdef sun
  26. # include "cdrom_sun.h"
  27. #endif
  28. #ifdef sgi
  29. # include "cdrom_sgi.h"
  30. #endif
  31.  
  32. void        cdrom_new_disc();
  33.  
  34. /*
  35.  * cb_cdrom_play checks to see if we're playing; if so do nothing.
  36.  * if not playing turns on playing.  if paused then return.
  37.  * otherwise start cd playing.
  38.  */
  39. /*ARGSUSED*/
  40. void
  41. cb_cdrom_play(widget, client_data, call_data)
  42.     Widget        widget;
  43.     XtPointer    client_data;
  44.     XtPointer    call_data;
  45. {
  46.     if (cdrom_open() == -1) {
  47.         debug_printf(1, "cb_cdrom_play: error from cdrom_open\n");
  48.         /* Turn the play button back off */
  49.         play_button_reset();
  50.         eject_button_set();
  51.         return;
  52.     }
  53.  
  54.     if (cdi.state & CDROM_STATE_EJECTED) {
  55.         cdrom_new_disc(widget);
  56.     }
  57.  
  58.     /* 
  59.      * toggle button weirdness; play and stop are radio toggles, ie. if
  60.      * you hit stop, and you are playing, play is supposed to stop, so
  61.      * toggle buttons automatically invoke the notify procedure of other
  62.      * members of a toggle group when another member of the toggle group
  63.      * is activated, before the requested notification takes place. 
  64.      * The practical upshot of this is that this routine can be called
  65.      * even if you didn't press play, and so it really takes no action.
  66.      */
  67.     if (cdi.state & CDROM_STATE_PLAY) {
  68.         debug_printf(1, "cb_cdrom_play: already playing track %d\n",
  69.                 cdi.curtrack);
  70.         return;
  71.     }
  72.  
  73.     if (cdi.curtrack == 0)     /* (no track selected) */
  74.     {
  75.         cdi.curtrack = cdi.mintrack;
  76.         track_button_update();
  77.     }
  78.  
  79.     cdi.state |= CDROM_STATE_PLAY;
  80.  
  81.     if (cdi.state & CDROM_STATE_PAUSE) {
  82.         debug_printf(1, "cb_cdrom_play: paused on track %d\n",
  83.                 cdi.curtrack);
  84.         return;
  85.     }
  86.  
  87.     timer_fsecs = 0;
  88.     cdi.duration = 0;
  89.  
  90.     if (cdi.state & CDROM_STATE_SHUFFLE) 
  91.         cdi.curtrack = shuffle_next_track();
  92.  
  93.     else if (cdi.state & CDROM_STATE_PROGRAM)
  94.     {
  95.         if ((cdi.curtrack = program_resume()) == 0) {
  96.  
  97.         /* cancel program */
  98.         debug_printf(1, "cb_cdrom_play: cancelling program\n");
  99.         program_cancel();
  100.             cdi.curtrack = cdi.mintrack;
  101.         }
  102.         else {
  103.         debug_printf(1, "cb_cdrom_play: resetting timer button\n");
  104.             timer_button_reset();
  105.         }
  106.     }
  107.  
  108.     if (cdrom_play() != -1) {
  109.         cdi.state &= ~CDROM_STATE_STOP;
  110.     }
  111.  
  112.     timer_button_update();
  113. }
  114.  
  115. /*
  116.  * cb_cdrom_pause toggles pausing on or off.
  117.  */
  118. /*ARGSUSED*/
  119. void
  120. cb_cdrom_pause(widget, client_data, call_data)
  121.     Widget        widget;
  122.     XtPointer    client_data;
  123.     XtPointer    call_data;
  124.  
  125. {
  126.     if (cdrom_open() == -1) {
  127.         debug_printf(1, "cb_cdrom_pause: error from cdrom_open\n");
  128.         pause_button_reset();
  129.         return;
  130.     }
  131.  
  132. #ifdef sgi
  133.     if (cdrom_status() == CDROM_NO_STATUS) {
  134.         cdi.state |= CDROM_STATE_EJECTED;
  135.         buttons_reset();
  136.         pause_button_reset();
  137.         return;
  138.     }
  139. #endif
  140.  
  141.     if (cdi.state & CDROM_STATE_EJECTED) {
  142.         cdrom_new_disc(widget);
  143.     }
  144.  
  145.     if (cdi.state & CDROM_STATE_PAUSE) {
  146.         cdi.state &= ~CDROM_STATE_PAUSE;
  147.  
  148.         if (cdi.state & CDROM_STATE_PROGRAM) 
  149.             cdi.curtrack = program_resume();
  150.  
  151.         else if (cdi.curtrack == 0)     /* (no track selected) */
  152.         {
  153.             cdi.curtrack = cdi.mintrack;
  154.             track_button_update();
  155.         }
  156.  
  157.         debug_printf(1, "cb_cdrom_pause: resuming track %d\n",
  158.                 cdi.curtrack);
  159.  
  160.         /*
  161.          * if we use next or prev after a pause we can't
  162.          * just resume but have to move to the track.
  163.          */
  164.         if ((cdi.curtrack == cdrom_get_curtrack())  &&
  165.             (cdi.duration > 0))
  166.         {
  167.             if (cdrom_resume() != -1) {
  168.                 cdi.state &= ~CDROM_STATE_EJECTED;
  169.                 eject_button_reset();
  170.                 cdi.state &= ~CDROM_STATE_STOP;
  171.             }
  172.  
  173.             cdrom_timer_on();
  174.  
  175.             return;
  176.         }
  177.  
  178.         if (cdrom_play() != -1) {
  179.             cdi.state &= ~CDROM_STATE_EJECTED;
  180.             eject_button_reset();
  181.             cdi.state &= ~CDROM_STATE_STOP;
  182.         }
  183.  
  184.         return;
  185.     }
  186.  
  187.     cdi.state |= CDROM_STATE_PAUSE;
  188.  
  189.     debug_printf(1, "cb_cdrom_pause: pausing on track %d\n",
  190.             cdi.curtrack);
  191.  
  192.     if (cdrom_pause() != -1) {
  193.         cdi.state &= ~CDROM_STATE_STOP;
  194.         cdi.state |= CDROM_STATE_PLAY;
  195.         eject_button_reset();
  196.         play_button_set();
  197.     }
  198.  
  199.     cdrom_timer_off();
  200. }
  201.  
  202. /*
  203.  * cb_cdrom_stop checks to see if we're playing; if not then
  204.  * do nothing.  sets the current track to the first audio track.
  205.  * turns off play, pause, stops the cd, and closes it so that the
  206.  * disc can be ejected with the eject button on the drive.
  207.  */
  208. /*ARGSUSED*/
  209. void
  210. cb_cdrom_stop(widget, client_data, call_data)
  211.     Widget        widget;
  212.     XtPointer    client_data;
  213.     XtPointer    call_data;
  214. {
  215.     Arg    args[1];
  216.     Boolean    state;
  217.  
  218.     if (cdrom_open() == -1) {
  219.         debug_printf(1, "cb_cdrom_stop: error from cdrom_open\n");
  220.         /* Turn the stop button back off */
  221.         stop_button_reset();
  222.         eject_button_set();
  223.         return;
  224.     }
  225.  
  226. #ifdef sgi
  227.     if (cdrom_status() == CDROM_NO_STATUS) {
  228.         cdi.state |= CDROM_STATE_EJECTED;
  229.         buttons_reset();
  230.         /* Turn the stop button back off */
  231.         stop_button_reset();
  232.         return;
  233.     }
  234. #endif
  235.  
  236.     /* toggle button weirdness; see comment in cb_cdrom_play for details */
  237.     XtSetArg(args[0], XtNstate, &state);
  238.     XtGetValues(widget, args, 1);
  239.  
  240.     if (state == False) {
  241.         debug_printf(1, "cb_cdrom_stop: already stopped\n");
  242.         return;
  243.     }
  244.  
  245.     debug_printf(1, "cb_cdrom_stop: resetting disc\n");
  246.  
  247.     cdrom_reset();
  248.  
  249.     if (cdi.state & CDROM_STATE_SHUFFLE) {
  250.         debug_printf(1, "cb_cdrom_shuffle: shuffle on\n");
  251.         cdi.state |= CDROM_STATE_SHUFFLE;
  252.         shuffle_setup();
  253.     }
  254. }
  255.  
  256. /*
  257.  * cb_cdrom_previous decrments the current track.  if paused or stopped
  258.  * then return.  otherwise start playing the (new) current track.
  259.  */
  260. /*ARGSUSED*/
  261. void
  262. cb_cdrom_previous(widget, client_data, call_data)
  263.     Widget        widget;
  264.     XtPointer    client_data;
  265.     XtPointer    call_data;
  266. {
  267.     if (cdrom_open() == -1) {
  268.         debug_printf(1, "cb_cdrom_previous: error from cdrom_open\n");
  269.         return;
  270.     }
  271.  
  272. #ifdef sgi
  273.     if (cdrom_status() == CDROM_NO_STATUS) {
  274.         cdi.state |= CDROM_STATE_EJECTED;
  275.         buttons_reset();
  276.         return;
  277.     }
  278. #endif
  279.  
  280.     cdi.state &= ~CDROM_STATE_EJECTED;
  281.     eject_button_reset();
  282.     cdi.state &= ~CDROM_STATE_STOP;
  283.  
  284.     cdrom_timer_off();
  285.  
  286.     /*
  287.      * if playing less than replayThreshold seconds, back up to 
  288.      * previous track; otherwise start at beginning of current track:
  289.      */
  290.     if (cdi.duration < replayThreshold)
  291.     {
  292.         if ((cdi.program != NULL) &&
  293.              (cdi.state & CDROM_STATE_PLAY) &&
  294.          ((cdi.state & CDROM_STATE_PAUSE) == 0))
  295.         {
  296.             if (program_prev_track() == 0) 
  297.                 debug_printf(1, "cb_cdrom_previous: no previous selections in program\n");
  298.             else
  299.         {
  300.                  debug_printf(1, "cb_cdrom_previous: going to prev selection\n");
  301.              cdi.curtrack = program_goto_prev_track();
  302.         }
  303.         }
  304.         else if (cdi.curtrack > cdi.mintrack) /* can't go below 1st track:*/
  305.             cdi.curtrack--;
  306.     }
  307.  
  308.     timer_fsecs = 0;
  309.     cdi.duration = 0;
  310.  
  311.     if (cdi.state & CDROM_STATE_SHUFFLE)
  312.         cdi.curtrack = shuffle_prev_track();
  313.  
  314.     track_button_update();
  315.     timer_button_update();
  316.  
  317.     if (cdi.state & CDROM_STATE_PAUSE) {
  318.         debug_printf(1, "cb_cdrom_previous: paused on track %d\n",
  319.                 cdi.curtrack);
  320.         if (cdrom_play() != -1) {
  321.             cdi.state &= ~CDROM_STATE_STOP;
  322.         }
  323.         if (cdrom_pause() != -1) {
  324.             cdi.state &= ~CDROM_STATE_STOP;
  325.         }
  326.         cdrom_timer_off();
  327.         return;
  328.     }
  329.  
  330.     if ((cdi.state & CDROM_STATE_PLAY) == 0) {
  331.         debug_printf(1, "cb_cdrom_previous: stopped on track %d\n",
  332.                 cdi.curtrack);
  333.         return;
  334.     }
  335.  
  336.     debug_printf(1, "cb_cdrom_previous: playing track %d\n",
  337.              cdi.curtrack);
  338.  
  339.  
  340.     /* restart playing if not paused and currently playing */
  341.     (void) cdrom_play();
  342. }
  343.  
  344.  
  345. /*
  346.  * cb_cdrom_next incrments the current track.  if paused or stopped
  347.  * then return.  otherwise start playing the (new) current track.
  348.  */
  349. /*ARGSUSED*/
  350. void
  351. cb_cdrom_next(widget, client_data, call_data)
  352.     Widget        widget;
  353.     XtPointer    client_data;
  354.     XtPointer    call_data;
  355. {
  356.     if (cdrom_open() == -1) {
  357.         debug_printf(1, "cb_cdrom_next: error from cdrom_open\n");
  358.         return;
  359.     }
  360.  
  361. #ifdef sgi
  362.     if (cdrom_status() == CDROM_NO_STATUS) {
  363.         cdi.state |= CDROM_STATE_EJECTED;
  364.         buttons_reset();
  365.         return;
  366.     }
  367. #endif
  368.  
  369.     if (cdi.state & CDROM_STATE_EJECTED) {
  370.         cdrom_new_disc(widget);
  371.     }
  372.  
  373.     cdi.state &= ~CDROM_STATE_EJECTED;
  374.     eject_button_reset();
  375.     cdi.state &= ~CDROM_STATE_STOP;
  376.  
  377.     if (cdi.state & CDROM_STATE_SHUFFLE) {
  378.         if (cdi.currand == cdi.ntracks) {
  379.             debug_printf(1, "cb_cdrom_next: at last track\n");
  380.             return;
  381.         }
  382.     }
  383.     else if ((cdi.program != NULL) &&
  384.              (cdi.state & CDROM_STATE_PLAY) &&
  385.          ((cdi.state & CDROM_STATE_PAUSE) == 0))
  386.     {
  387.         if (program_next_track() == 0)
  388.             debug_printf(1, "cb_cdrom_next: no further selections in program\n");
  389.         else
  390.         {
  391.             debug_printf(1, "cb_cdrom_next: going to next selection\n");
  392.             cdi.curtrack = program_goto_next_track();
  393.         }
  394.     }
  395.     else {
  396.         if (cdi.curtrack >= cdi.maxtrack) {
  397.             debug_printf(1, "cb_cdrom_next: at last track\n");
  398.             return;
  399.         }
  400.         else
  401.             cdi.curtrack++;
  402.     }
  403.  
  404.     cdrom_timer_off();
  405.  
  406.     timer_fsecs = 0;
  407.     cdi.duration = 0;
  408.  
  409.  
  410.     track_button_update();
  411.     timer_button_update();
  412.  
  413.     if (cdi.state & CDROM_STATE_PAUSE) {
  414.         debug_printf(1, "cb_cdrom_next: paused on track %d\n",
  415.                 cdi.curtrack);
  416.         if (cdrom_play() != -1) {
  417.             cdi.state &= ~CDROM_STATE_STOP;
  418.         }
  419.         if (cdrom_pause() != -1) {
  420.             cdi.state &= ~CDROM_STATE_STOP;
  421.         }
  422.         cdrom_timer_off();
  423.         return;
  424.     }
  425.  
  426.     if ((cdi.state & CDROM_STATE_PLAY) == 0) {
  427.         debug_printf(1, "cb_cdrom_next: stopped on track %d\n",
  428.                 cdi.curtrack);
  429.         return;
  430.     }
  431.  
  432.     if (cdi.state & CDROM_STATE_SHUFFLE)
  433.         cdi.curtrack = shuffle_next_track();
  434.  
  435.     debug_printf(1, "cb_cdrom_next: playing track %d\n",
  436.             cdi.curtrack);
  437.  
  438.     /* restart playing if not paused and currently playing */
  439.     (void) cdrom_play();
  440. }
  441.  
  442.  
  443. /*ARGSUSED*/
  444. void
  445. cb_cdrom_eject(widget, client_data, call_data)
  446.     Widget        widget;
  447.     XtPointer    client_data;
  448.     XtPointer    call_data;
  449. {
  450.     Arg    args[1];
  451.     Boolean    state;
  452.  
  453.     if (cdrom_open() == -1) {
  454.         debug_printf(1, "cb_cdrom_eject: error from cdrom_open\n");
  455.         return;
  456.     }
  457.  
  458. #ifdef sgi
  459.     if (cdrom_status() == CDROM_NO_STATUS) {
  460.         cdi.state |= CDROM_STATE_EJECTED;
  461.         buttons_reset();
  462.         return;
  463.     }
  464. #endif
  465.  
  466.     /* Check if this is just a toggle event.  If so, do nothing */
  467.     XtSetArg(args[0], XtNstate, &state);
  468.     XtGetValues(widget, args, 1);
  469.     if (state == False) {
  470.         return;
  471.     }
  472.  
  473.     /* toggle button weirdness; see comment in cb_cdrom_play for details */
  474.     if (cdi.state & CDROM_STATE_EJECTED) {
  475.         debug_printf(1, "cb_cdrom_eject: already ejected\n");
  476.         return;
  477.     }
  478.  
  479.     debug_printf(1, "cb_cdrom_eject: ejecting on track %d\n",
  480.             cdi.curtrack);
  481.  
  482.     cdrom_reset();
  483.     cdi.maxtrack = 0;
  484.  
  485.     program_cancel();
  486.     cdrom_eject();
  487.     cdi.state |= CDROM_STATE_EJECTED;
  488.     cdrom_close();
  489.  
  490.     disc_title = NODISCSTR;
  491.     update_title();
  492. }
  493.  
  494. #ifdef sgi
  495. /*ARGSUSED*/
  496. void
  497. cb_cdrom_audio(widget, client_data, call_data)
  498.     Widget        widget;
  499.     XtPointer    client_data;
  500.     XtPointer    call_data;
  501. {
  502.     if (cdrom_open() == -1) {
  503.         debug_printf(1, "cb_cdrom_audio: error from cdrom_open\n");
  504.         return;
  505.     }
  506.  
  507.     if (cdi.state & CDROM_STATE_PLAY) {
  508.         XBell(XtDisplay(widget), 100);
  509.         if (cdi.scsi_audio) {
  510.             audio_button_set();
  511.         } else {
  512.             audio_button_reset();
  513.         }
  514.         return;
  515.     }
  516.  
  517.     if (cdi.scsi_audio) {
  518.         debug_printf(1, "cb_cdrom_audio: toggling audio off\n");
  519.         cdrom_toggle_audio();
  520.         audio_button_reset();
  521.         return;
  522.     }
  523.  
  524.     /* Check if it's available before turning it on */
  525.     if ( cdrom_audio_avail() ) {
  526.         debug_printf(1, "cb_cdrom_audio: toggling audio on\n");
  527.         cdrom_toggle_audio();
  528.         audio_button_set();
  529.         return;
  530.     }
  531.     XBell(XtDisplay(widget), 100);
  532.     audio_button_reset();
  533. }
  534. #endif /* sgi */
  535.  
  536. /*ARGSUSED*/
  537. void
  538. cb_cdrom_cycle(widget, client_data, call_data)
  539.     Widget        widget;
  540.     XtPointer    client_data;
  541.     XtPointer    call_data;
  542. {
  543.     if (cdi.state & CDROM_STATE_CYCLE) {
  544.         debug_printf(1, "cb_cdrom_cycle: cycle off\n");
  545.         cdi.state &= ~CDROM_STATE_CYCLE;
  546.  
  547.         return;
  548.     }
  549.  
  550.     debug_printf(1, "cb_cdrom_cycle: cycle on\n");
  551.     cdi.state |= CDROM_STATE_CYCLE;
  552. }
  553.  
  554. /*ARGSUSED*/
  555. void
  556. cb_cdrom_shuffle(widget, client_data, call_data)
  557.     Widget        widget;
  558.     XtPointer    client_data;
  559.     XtPointer    call_data;
  560. {
  561.     if (cdi.state & CDROM_STATE_SHUFFLE) {
  562.  
  563.         debug_printf(1, "cb_cdrom_shuffle: shuffle off\n");
  564.         cdi.state &= ~CDROM_STATE_SHUFFLE;
  565.  
  566.         return;
  567.     }
  568.  
  569.     if (cdi.state & CDROM_STATE_PLAY) {
  570.         XBell(XtDisplay(widget), 100);
  571.         shuffle_button_reset();
  572.         return;
  573.     }
  574.  
  575.     if (cdi.state & CDROM_STATE_PROGRAM) {
  576.         debug_printf(1, "cb_cdrom_shuffle: cancelling program\n");
  577.         program_cancel();
  578.     }
  579.  
  580.     debug_printf(1, "cb_cdrom_shuffle: shuffle on\n");
  581.     cdi.state |= CDROM_STATE_SHUFFLE;
  582.     shuffle_setup();
  583. }
  584.  
  585. /*ARGSUSED*/
  586. void
  587. cb_cdrom_quit(widget, client_data, call_data)
  588.     Widget        widget;
  589.     XtPointer    client_data;
  590.     XtPointer    call_data;
  591. {
  592.     debug_printf(1, "cb_cdrom_quit: bye\n");
  593.  
  594.     cdrom_timer_off();
  595.     cdrom_close();
  596.  
  597.     exit(0);
  598. }
  599.  
  600.  
  601. /*ARGSUSED*/
  602. void
  603. cb_cdrom_rewind(widget, client_data, call_data)
  604.     Widget        widget;
  605.     XtPointer    client_data;
  606.     XtPointer    call_data;
  607. {
  608.     if (cdrom_open() == -1) {
  609.         debug_printf(1, "cb_cdrom_rew: error from cdrom_open\n");
  610.         return;
  611.     }
  612.  
  613.     if ((cdi.state & CDROM_STATE_PLAY) || (cdi.state & CDROM_STATE_PAUSE)) {
  614.         debug_printf(1, "cb_cdrom_rew: moving backward in track %d\n",
  615.                 cdi.curtrack);
  616.  
  617.         cdrom_rewind();
  618.     }
  619. }
  620.  
  621.  
  622. /*ARGSUSED*/
  623. void
  624. cb_cdrom_ff(widget, client_data, call_data)
  625.     Widget        widget;
  626.     XtPointer    client_data;
  627.     XtPointer    call_data;
  628. {
  629.     if (cdrom_open() == -1) {
  630.         debug_printf(1, "cb_cdrom_ff: error from cdrom_open\n");
  631.         return;
  632.     }
  633.  
  634.  
  635.     if ((cdi.state & CDROM_STATE_PLAY) || (cdi.state & CDROM_STATE_PAUSE)) {
  636.         debug_printf(1, "cb_cdrom_ff: moving forward in track %d\n",
  637.                 cdi.curtrack);
  638.  
  639.         cdrom_ff();
  640.     }
  641. }
  642.  
  643. static Boolean pgmButtonUp = False;
  644.  
  645. /*ARGSUSED*/
  646. void
  647. cb_cdrom_program(widget, topLevel, call_data)
  648.     Widget        widget;
  649.     Widget        topLevel;
  650.     XtPointer    call_data;
  651. {
  652.     if (pgmButtonUp)
  653.     {
  654.         track_button_reset();
  655.         pgm_button_set();
  656.  
  657.         /*
  658.              * have to keep track of button position internally, since toggle
  659.              * widgets screw up when you mess with their state programatically,
  660.              * in that if you set the state to false when notified on a button
  661.              * press, if you also notify on button release, the state is
  662.              * auto-reset to true prior to notification, so there is no
  663.              * longer any way to tell if it's a button release:
  664.              * THIS IS A HACK! (necessary, but *still* a hack.)
  665.              */
  666.             pgmButtonUp = False;
  667.  
  668.         return;
  669.     }
  670.  
  671.     if ((cdi.state & CDROM_STATE_PROGRAM) == 0)
  672.     {
  673.         if (cdrom_open() == -1) {
  674.         debug_printf(1, "cb_cdrom_play: error from cdrom_open\n");
  675.         return;
  676.         }
  677.         if (cdi.state & CDROM_STATE_EJECTED) {
  678.             cdrom_new_disc(widget);
  679.         }
  680.         if (cdi.state & CDROM_STATE_SHUFFLE) {
  681.             debug_printf(1, "cb_cdrom_program: cancelling shuffle mode\n");
  682.             cdi.state &= ~CDROM_STATE_SHUFFLE;
  683.         shuffle_button_reset();
  684.         }
  685.         cdi.state &= ~CDROM_STATE_EJECTED;
  686.         eject_button_reset();
  687.         cdi.state &= ~CDROM_STATE_STOP;
  688.  
  689.         debug_printf(1, "cb_cdrom_program: program on\n");
  690.         cdi.state |= CDROM_STATE_PROGRAM;
  691.         timer_button_set();
  692.         popup_program_form (widget, topLevel, call_data);
  693.             /*
  694.              * have to keep track of button position internally, since command
  695.              * widgets screw up if you mess with their state programatically:
  696.              */
  697.             pgmButtonUp = True;
  698.         return;
  699.     }
  700.  
  701.     if (((cdi.state & CDROM_STATE_PAUSE) || 
  702.          ((cdi.state & CDROM_STATE_PLAY) == 0)) &&
  703.         (cdi.curtrack != 0))
  704.     {
  705.         /* indicate to user he's programmed a track: */
  706.         pgm_button_reset();
  707.         track_button_set();
  708.         timer_button_update();
  709.  
  710.         debug_printf(1, "cb_cdrom_program: adding track %d to program list\n",
  711.         cdi.curtrack);
  712.         program_add_track (cdi.curtrack);
  713.     }
  714.         /*
  715.          * have to keep track of button position internally, since command
  716.          * widgets screw up if you mess with their state programatically:
  717.          */
  718.         pgmButtonUp = True;
  719.  
  720. }
  721.  
  722.  
  723. void
  724. cdrom_new_disc(widget)
  725.     Widget    widget;
  726. {
  727.     Arg    args[1];
  728.     Boolean    state;
  729.  
  730.     debug_printf(1, "cdrom_new_disc: resetting disc\n");
  731.  
  732.     cdrom_reset();
  733.     
  734.     cdi.state &= ~CDROM_STATE_EJECTED;
  735.     eject_button_reset();
  736.  
  737.     /* toggle button weirdness; see comment in cb_cdrom_play for details */
  738.     XtSetArg(args[0], XtNstate, &state);
  739.     XtGetValues(widget, args, 1);
  740.     if (state == False) {
  741.         XtSetArg(args[0], XtNstate, True);
  742.         XtSetValues(widget, args, 1);
  743.     }
  744.  
  745.     if (cdi.state & CDROM_STATE_SHUFFLE) {
  746.         debug_printf(1, "cb_cdrom_shuffle: shuffle on\n");
  747.         cdi.state |= CDROM_STATE_SHUFFLE;
  748.         shuffle_setup();
  749.     }
  750. }
  751.